#ifndef MS_C_MEM_BASE_H
#define MS_C_MEM_BASE_H


#include "types.h"

#define ms_malloc   malloc
#define ms_calloc   calloc
#define ms_realloc  realloc
#define ms_free     free

typedef struct ms_alloc_s {
    void*( *allocate)(void* self, size_t size);
    void ( *deallocate)(void* self, void *p);
    void*( *reallocate)(void* self, void *p, size_t size);
} ms_alloc_t;

static inline void* ms_malloc_default(void* self, size_t size) {
    return ms_malloc(size);
}

static inline void ms_free_default(void* self, void* p) {
    ms_free(p);
}

static inline void* ms_realloc_default(void* self, void* p, size_t size) {
    return ms_realloc(p, size);
}

CPUBLIC ms_alloc_t* ms_global_alloc() {
    static ms_alloc_t a = {ms_malloc_default, ms_free_default, ms_realloc_default};
    return &a;
}

CPUBLIC void* ms_allocate(void* self, size_t size) {
    return ((ms_alloc_t*)self)->allocate(self, size);
}

CPUBLIC void ms_deallocate(void* self, void* p) {
    ((ms_alloc_t*)self)->deallocate(self, p);
}

CPUBLIC void* ms_reallocate(void* self, void* p, size_t size) {
    if (((ms_alloc_t*)self)->reallocate) {
        return ((ms_alloc_t*)self)->reallocate(self, p, size);
    }
    void* newp = ms_allocate(self, size);
    if (newp) {
        memcpy(newp, p, size);
        ms_deallocate(self, p);
    }
    return newp;
}
#endif // MS_C_MEM_BASE_H
